package com.zyx.netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.ResourceLeakDetector;
import lombok.extern.slf4j.Slf4j;

/**
 * 描述说明:
 *
 * @author DQing
 * @version 1.0
 * @className AbstractControlServer
 * @date 2020/5/1 22:41
 */
@Slf4j
public abstract class AbstractControlServer {

    protected Channel channel;

    protected ChannelFuture startServer(int port,
                                        NioEventLoopGroup bossGroup,
                                        NioEventLoopGroup workerGroup,
                                        ChannelInitializer channelInitializer)
            throws Exception {
        ChannelFuture f = null;
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .option(ChannelOption.SO_KEEPALIVE,true)
                    .option(ChannelOption.RCVBUF_ALLOCATOR,new FixedRecvByteBufAllocator(1024*1024))
                    .childOption(ChannelOption.TCP_NODELAY, true)
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childHandler(channelInitializer);
            //内存泄漏检测 开发推荐PARANOID 线上SIMPLE
            ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.SIMPLE);
            f = b.bind(port).sync();
            channel = f.channel();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (f != null && f.isSuccess()) {
                log.info("Netty server listening on port " + port + " and ready for connections...");
            } else {
                log.error("Netty server start up Error!");
            }
        }
        return f;
    }

    /**
     * 停止服务
     */
    protected void destroyServer(NioEventLoopGroup bossGroup,NioEventLoopGroup workerGroup) {
        log.info("Shutdown Netty Server...");
        if(channel != null) { channel.close();}
        workerGroup.shutdownGracefully();
        bossGroup.shutdownGracefully();
        log.info("Shutdown Netty Server Success!");
    }
}
